<template>
  <div class="painting-signature">
    <van-nav-bar class="top-bar" :border="false" placeholder fixed>
      <template #left>
        <svg-icon name="arrows" @click="topReturnClick" />
      </template>
      <template #title>
        <span class="contract-title">手写签名</span>
      </template>
    </van-nav-bar>
    <div id="my-canvas">
      <canvas
        ref="myCanvas"
        @touchstart="mStart"
        @touchmove="mMove"
        @touchend="mEnd"
      ></canvas>
    </div>
    <div class="signing-btn">
      <div class="left">
        <div class="black" @click="penColor = '#000'">
          {{ penColor === '#000' ? '✓' : '' }}
        </div>
        <div class="blue" @click="penColor = '#2489f2'">
          {{ penColor === '#2489f2' ? '✓' : '' }}
        </div>
        <div class="red" @click="penColor = 'red'">
          {{ penColor === 'red' ? '✓' : '' }}
        </div>
      </div>
      <div class="right">
        <div class="delete-btn" @click="cleanCanvas">清除</div>
        <div class="confirm-btn" @click="saveCanvas">确定</div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'

import { postSealSignature } from '@/api/contract'
export default defineComponent({
  setup() {
    const router = useRouter()
    const topReturnClick = () => {
      router.go(-1)
    }
    // 改变屏幕
    let evt = 'resize' // 当前屏幕
    const detectOrient = () => {
      const width = document.documentElement.clientWidth
      const height = document.documentElement.clientHeight
      const div: HTMLDivElement = document.querySelector('.painting-signature')!
      if (width >= height) {
        // 横屏
        evt = 'orientationchange'
        div.style.width = `${width}px`
        div.style.height = `${height}px`
        div.style.transform = 'rotate(0deg)'
        div.style.transformOrigin = `0 0`
        // alert('横屏下不能获得最佳体验,建议竖屏浏览网页!')
      } else {
        // 竖屏
        evt = 'resize'
        div.style.width = `${height}px`
        div.style.height = `${width}px`
        div.style.transform = 'rotate(90deg)'
        div.style.transformOrigin = `${width / 2}px ${width / 2}px`
      }
      init()
    }
    onMounted(() => {
      detectOrient()
      window.onresize = detectOrient
    })
    // 绘画签名
    const canvasData = reactive({
      x: 0,
      y: 0
    })
    const myCanvas = ref<HTMLCanvasElement>()
    let moving = false // 是否正在绘制中且移动
    let drawingStart = false // 画布上是否有内容
    let penColor = ref('#000') // 画笔颜色
    let canvasWidth = 0 // 画布宽
    let canvasHeight = 0 // 画布高
    // 初始化
    const init = () => {
      const div: HTMLDivElement = document.querySelector('#my-canvas')!
      myCanvas.value!.width = div.offsetWidth
      myCanvas.value!.height = div.offsetHeight
      canvasWidth = div.offsetWidth
      canvasHeight = div.offsetHeight
      const ctx = myCanvas.value!.getContext('2d') as CanvasRenderingContext2D
      drawingStart = false
      ctx.clearRect(0, 0, canvasWidth, canvasHeight) //清空所有的内容
      ctx.fillStyle = '#DCDBDB' // 颜色
      ctx.font = '700 24px PingFangSC'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText('签名区', div.offsetWidth / 2, div.offsetHeight / 2)
    }
    const approve = (e: any) => {
      e.preventDefault()
    }
    const mStart = (e: any) => {
      const ctx = myCanvas.value!.getContext('2d') as CanvasRenderingContext2D
      ctx.strokeStyle = `${penColor.value}` // 颜色
      ctx.lineWidth = 3 // 线条宽度
      const touch = e.touches[0] ?? e
      canvasData.x = touch.clientX - myCanvas.value!.offsetLeft
      canvasData.y = touch.clientY - myCanvas.value!.offsetTop
      ctx.beginPath()
      moving = true
      // 判断是否有内容
      if (!drawingStart) {
        ctx.clearRect(0, 0, canvasWidth, canvasHeight) //清空所有的内容
        drawingStart = true
      }
      window.addEventListener('touchmove', approve, {
        passive: false
      })
    }
    const mMove = (e: any) => {
      const ctx = myCanvas.value!.getContext('2d') as CanvasRenderingContext2D
      const touch = e.touches[0] ?? e
      if (moving) {
        const x = touch.clientX - myCanvas.value!.offsetLeft
        const y = touch.clientY - myCanvas.value!.offsetTop // 获取触摸点在画板（canvas）的坐标
        if (evt === 'resize') {
          // 强制横屏
          ctx.moveTo(
            canvasData.y,
            document.documentElement.clientWidth - canvasData.x - 46
          )
          ctx.lineTo(y, document.documentElement.clientWidth - x - 46)
        } else if (evt === 'orientationchange') {
          // 横屏
          ctx.moveTo(canvasData.x, canvasData.y - 46) // 把路径移动到画布中的指定点，不创建线条(起始点)
          ctx.lineTo(x, y - 46) // 添加一个新点，然后创建从该点到画布中最后指定点的线条，不创建线条
        }
        ctx.stroke() // 绘制
        canvasData.x = x
        canvasData.y = y // 重置点坐标为上一个坐标
      }
    }
    const mEnd = () => {
      const ctx = myCanvas.value!.getContext('2d') as CanvasRenderingContext2D
      if (moving) {
        ctx.closePath() // 停止绘制
        moving = false // 关闭绘制开关
        // 移除页面默认行为
        window.removeEventListener('touchmove', approve)
      }
    }

    // 清除画布
    const cleanCanvas = () => {
      init()
    }

    // 保存画布
    const saveCanvas = async () => {
      const canvasURL = myCanvas.value!.toDataURL('image/png')
      const params = {
        sealId: new Date().getTime(),
        sealImage: canvasURL
      }
      const res = await postSealSignature(params)
      if (res.code !== '0') return
      cleanCanvas()
      router.go(-1)
    }
    return {
      myCanvas,
      penColor,
      topReturnClick,
      mStart,
      mMove,
      mEnd,
      cleanCanvas,
      saveCanvas
    }
  }
})
</script>

<style scoped lang="less">
.painting-signature {
  height: 100%;
  width: 100%;
  overflow: hidden;
  .top-bar {
    height: 46px !important;
  }
  .contract-title {
    font-size: 17px;
    color: #101010;
    font-weight: 700;
  }
  #my-canvas {
    position: relative;
    width: 100%;
    height: calc(100% - 96px);
  }
  .signing-btn {
    box-sizing: border-box;
    width: 100%;
    height: 50px;
    padding: 0 30px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .left {
      display: flex;
      .black {
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background-color: #000;
        margin-right: 20px;
        line-height: 24px;
        text-align: center;
        font-size: 16px;
        color: #fff;
      }
      .red {
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background-color: red;
        margin-right: 20px;
        line-height: 24px;
        text-align: center;
        font-size: 16px;
        color: #fff;
      }
      .blue {
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background-color: #2489f2;
        margin-right: 20px;
        line-height: 24px;
        text-align: center;
        font-size: 16px;
        color: #fff;
      }
    }
    .right {
      display: flex;
      .delete-btn {
        width: 60px;
        height: 34px;
        border-radius: 4px;
        line-height: 34px;
        text-align: center;
        background-color: #fff;
        font-size: 16px;
        color: #101010;
      }
      .confirm-btn {
        width: 60px;
        height: 34px;
        border-radius: 4px;
        margin-left: 20px;
        background-color: #2489f2;
        line-height: 34px;
        text-align: center;
        font-size: 16px;
        color: #fff;
      }
    }
  }
}
</style>
